package com.aluka.nirvana.framework.datasource.dynamic;

import com.alibaba.druid.pool.DruidDataSource;
import com.aluka.nirvana.framework.datasource.constant.NirvanaDataSource;
import com.aluka.nirvana.framework.datasource.model.DataSourceWrap;
import com.aluka.nirvana.framework.datasource.util.EnvironmentPaser;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.GenericBeanDefinition;

import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;

/**
 * 动态数据源注入
 * @author gongli
 */
@Slf4j
public class DynamicDataSourceRegister{

	private DynamicDataSourceRegister(){}

	private static DynamicDataSourceRegister dynamicDataSourceRegister = new DynamicDataSourceRegister();

	public static DynamicDataSourceRegister getInstance(){
		return dynamicDataSourceRegister;
	}

	private DataSource primaryDataSource;

	private Map<String, Object> customsDataSources = new HashMap<>();

	/**
	 * 注入注解驱动数据源使用的AbstractRoutingDataSource.class
	 * @param registry Bean注册类
	 */
	public void registerBeanDefinitions(BeanDefinitionRegistry registry) {
		// 添加数据源
		Map<Object, Object> targetDataSources = new HashMap<>(customsDataSources);
		DynamicDataSourceContextHolder.dataSourceIds.addAll(customsDataSources.keySet());

		GenericBeanDefinition dynamicDataSource = new GenericBeanDefinition();
		dynamicDataSource.setBeanClass(DynamicDataSource.class);
		dynamicDataSource.setSynthetic(true);
		MutablePropertyValues mpv = dynamicDataSource.getPropertyValues();
		mpv.addPropertyValue("defaultTargetDataSource", primaryDataSource);
		mpv.addPropertyValue("targetDataSources", targetDataSources);
		registry.registerBeanDefinition(NirvanaDataSource.DATA_SOURCE, dynamicDataSource);

		GenericBeanDefinition dynamicDataSourceAspect = new GenericBeanDefinition();
		dynamicDataSourceAspect.setBeanClass(DynamicDataSourceAspect.class);
		dynamicDataSourceAspect.setSynthetic(true);
		registry.registerBeanDefinition("dynamicDataSourceAspect",dynamicDataSourceAspect);
		log.info(">>Nirvana<< 初始化注解驱动数据源成功 >> {}",customsDataSources.keySet());
	}

	/**
	 * 设置数据源信息
	 * @param druidDataSourceMap 数据源配置信息
	 */
	public void setDataSource(Map<String ,DataSourceWrap> druidDataSourceMap) {
		druidDataSourceMap.forEach((k,v) -> {
			DruidDataSource dataSource = new DruidDataSource();
			EnvironmentPaser.druidPropSetting(dataSource,v);
			Boolean isPrimary = v.getIsPrimary();
			if(null != isPrimary && isPrimary){
				DynamicDataSourceContextHolder.DEFAULT = k;
				primaryDataSource = dataSource;
			}
			customsDataSources.put(k, dataSource);
		});
	}

}
